/*******************************************************************************
**
** Copyright (c) 2011 - The OWE Team
**
** This file is part of OWE.
**
** OWE is a free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; version
** version 2.1 of the License.
**
** OWE is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with OWE. If not, see <http://www.gnu.org/licenses/>.
**
*******************************************************************************/

#include <cstring>

#include <owe/authorelement.h>
#include <owe/contentelement.h>
#include <owe/descriptionelement.h>
#include <owe/element.h>
#include <owe/featureelement.h>
#include <owe/iconelement.h>
#include <owe/licenseelement.h>
#include <owe/nameelement.h>
#include <owe/node.h>
#include <owe/paramelement.h>
#include <owe/preferenceelement.h>
#include <owe/textelement.h>
#include <owe/ustring.h>
#include <owe/widgetelement.h>

OWE_USE_NAMESPACE

/*!
    \class Element
    \brief Base class of all elements.

    \ingroup Configuration

    Elements it the base class of all elements that can occur on a config.xml
    file. All possible elements are specified
    <a href="http://www.w3.org/TR/widgets/#table-of-elements-and-their-attributes">
    here</a>.
*/

/*!
    \enum Element::ElementType

    The type attribute aims to help the API users to classify an Element and
    after that, safely do a static_cast to it's original form.

    \var Element::ElementType Element::None
        Dummy element created when using a invalid Node. *//*!
    \var Element::ElementType Element::Widget
        Root of widget configuration, hold most of attributes and
        child elements as decribed
        <a href="http://www.w3.org/TR/widgets/#widget0">here</a>. Can be casted
        to WidgetElement. *//*!
    \var Element::ElementType Element::Name
        Contains the abbreviated widget name so as the long name.
        Specified <a href="http://www.w3.org/TR/widgets/#name">here</a>. Can be
        casted to NameElement. *//*!
    \var Element::ElementType Element::Description
        Contains a long description about the widget and it's purpose.
        Specified <a href="http://www.w3.org/TR/widgets/#description">here</a>.
        Can be casted to DescriptionElement. *//*!
    \var Element::ElementType Element::Author
        Contains the widget's author information such as name and email.
        Specified <a href="http://www.w3.org/TR/widgets/#author0">here</a>.
        Can be casted to AuthorElement. *//*!
    \var Element::ElementType Element::Feature
        Contains the resources needed by the widget.
        Specified <a href="http://www.w3.org/TR/widgets/#feature">here</a>.
        Can be casted to FeatureElement. *//*!
    \var Element::ElementType Element::Preference
        Contains the widget's preferences data.
        Specified <a href="http://www.w3.org/TR/widgets/#preference">here</a>.
        Can be casted to PreferenceElement. *//*!
    \var Element::ElementType Element::Param
        Contains the feature's custom parameters.
        Specified <a href="http://www.w3.org/TR/widgets/#param">here</a>.
        Can be casted to ParamElement. *//*!
    \var Element::ElementType Element::License
        Contains the widget's license information
        Specified <a href="http://www.w3.org/TR/widgets/#license">here</a>.
        Can be casted to LicenseElement. *//*!
    \var Element::ElementType Element::Content
        Contains the widget's custom start html information
        Specified <a href="http://www.w3.org/TR/widgets/#content">here</a>.
        Can be casted to ContentElement. *//*!
    \var Element::ElementType Element::Icon
        Contains the widget's icon information
        Specified <a href="http://www.w3.org/TR/widgets/#icon0">here</a>.
        Can be casted to IconElement. *//*!
    \var Element::ElementType Element::Text
        Generic element that holds the text node. Specified
        <a href="http://www.w3.org/TR/widgets/#text-node">here</a>. Can be
        casted to TextElement.
*/

/*!
    \fn ElementType Element::type() const

    Return the element type. Useful for static casting an Element to a
    specialized class.
*/

/*!
    \fn UString Element::lang() const

    Return the element language if supported or an empty string otherwise. See
    attribute <a href="http://www.w3.org/TR/widgets/#xmllang">xml:lang</a>
    for more details.
*/

/*!
    \fn UString Element::dir() const

    Return the element language directionally if supported or an empty string
    otherwise. See attribute <a href="http://www.w3.org/TR/widgets/#dir">dir</a>
    for more details.
*/

/*!
    \fn UString Element::text() const

    Returns the contents of the text node.
*/

/*!
    This Element factory creates an Element based on a given \a node. It returns
    a dummy element with type Element::None with if node has not a valid
    content. This should be the standard way of creating any kind of Element.
*/
Element *Element::fromNode(const Node *node)
{
    if (!node)
        return new Element(0);

    if (node->name() == "widget")
        return new WidgetElement(node);
    else if (node->name() == "name")
        return new NameElement(node);
    else if (node->name() == "description")
        return new DescriptionElement(node);
    else if (node->name() == "author")
        return new AuthorElement(node);
    else if (node->name() == "feature")
        return new FeatureElement(node);
    else if (node->name() == "preference")
        return new PreferenceElement(node);
    else if (node->name() == "param")
        return new ParamElement(node);
    else if (node->name() == "license")
        return new LicenseElement(node);
    else if (node->name() == "content")
        return new ContentElement(node);
    else if (node->name() == "icon")
        return new IconElement(node);
    else if (node->name() == "text")
        return new TextElement(node);

    return new Element(0);
}

/*!
    Constructs a new Element. This constructor should never be used from outside
    the Element factory. It will not take ownership of the \a node, that should
    be released from outside this class. The attribute \a type stands for
    Element type and should be passed by the inherited class constructor.
*/
Element::Element(const Node *node, ElementType type)
    : m_type(type)
{
    if (type == None || !node)
        return;

    m_lang = node->attribute("xml:lang");
    m_dir = node->attribute("dir");
}

/*!
    Destructs the object releasing all allocated resources.
*/
Element::~Element()
{
}

/*!
    Add a text \a element.

    \todo span tags are not supported.
*/
bool Element::addText(TextElement *element)
{
    if (element)
        m_text.append(element->content());

    delete element;

    return true;
}

/*!
    Add a \a element to the tree. By adding a child element, the parent takes
    ownership and is responsible for freeing child resources (no matter whether
    the child element is accepted or not).

    Returns true if the element is valid as child element, false otherwise.
*/
bool Element::addChild(Element *element)
{
    delete element;

    return false;
}
